<template>
  <div class="form-edit-container">
    <div class="left-board">
      <el-tabs
        class="left-tabs"
        tab-position="left"
        v-model="leftTabActive"
      >
        <el-tab-pane name="components">
          <template #label>
            <span class="tabs-label">
              <el-icon size="24">
                <TablerCategory2 />
              </el-icon>
              <span>{{ $t("formgen.index.subject") }}</span>
            </span>
          </template>
          <el-scrollbar
            :height="`${wdHeight - 100}px`"
            class="left-scrollbar"
          >
            <div class="components-list">
              <div
                v-for="(item, listIndex) in leftComponents"
                :key="listIndex"
              >
                <div class="components-title">
                  {{ item.title }}
                </div>
                <draggable
                  v-model="item.list"
                  :clone="handleCloneComponent"
                  :force-fallback="true"
                  :group="{ name: 'componentsGroup', pull: 'clone', put: false }"
                  :animation="180"
                  :move="handleMove"
                  :scroll="true"
                  :scroll-sensitivity="0"
                  :sort="false"
                  class="components-draggable"
                  item-key="config.label"
                  @end="onEnd"
                >
                  <template #item="{ element }">
                    <div class="components-item">
                      <div
                        class="components-body"
                        @click="addComponent(element)"
                      >
                        <form-svg-icon :name="element.config.tagIcon" />
                        {{ element.config.label }}
                      </div>
                    </div>
                  </template>
                </draggable>
              </div>
            </div>
          </el-scrollbar>
        </el-tab-pane>
        <el-tab-pane name="outline">
          <template #label>
            <span class="tabs-label">
              <el-icon size="24">
                <TablerNotes />
              </el-icon>
              <span>{{ $t("formgen.index.outline") }}</span>
            </span>
          </template>
          <form-outline
            v-if="leftTabActive == 'outline'"
            :form-key="formKey"
            @scroll-to-field="handleFormScrollToField"
          />
        </el-tab-pane>
        <el-tab-pane class="questionBank">
          <template #label>
            <span class="tabs-label">
              <el-icon size="24">
                <TablerBook2 />
              </el-icon>
              <span>{{ $t("formgen.index.questionBank") }}</span>
            </span>
          </template>
          <form-question @add="addComponent" />
        </el-tab-pane>
      </el-tabs>
    </div>
    <div class="center-board">
      <fast-toolbar />
      <el-scrollbar
        ref="centerScrollbarRef"
        class="center-scrollbar"
        @scroll="handleContentScroll"
      >
        <div
          v-if="formConf"
          ref="centerRowsRef"
          class="center-board-row t-form-theme-wrap"
        >
          <div
            v-if="editFormInfo"
            class="form-desc-wrap"
          >
            <div class="center-name-box">
              <form-tinymce
                v-model:value="formConf.title"
                :inline="true"
                @change="handleSaveProjectInfo"
              />
            </div>
            <div class="center-desc-box">
              <form-tinymce
                v-model:value="formConf.description"
                :inline="true"
                @change="handleSaveProjectInfo"
              />
            </div>
            <div
              v-if="formConf.type == 4"
              class="evaluation-total-score"
            >
              <div class="total-score-title">{{ $t("formgen.index.total") }}</div>
              <div class="total-score">
                {{ totalScore }}
              </div>
            </div>
          </div>
          <async-loading v-if="loading" />
          <el-form
            :label-position="formConf.labelPosition"
            :label-width="formConf.labelWidth + 'px'"
            class="design-form"
            size="default"
            ref="designFormRef"
            :show-message="false"
          >
            <div
              v-if="!drawingList || !drawingList.length"
              class="empty-info"
            >
              <el-icon
                class="mr5 pointer"
                size="18"
              >
                <ele-Position />
              </el-icon>
              {{ $t("formgen.index.leftQuestion") }}
              <el-icon
                class="ml5 mr5"
                size="18"
              >
                <ele-Rank />
              </el-icon>
              {{ $t("formgen.index.drag") }}
            </div>
            <draggable
              v-model="drawingList"
              :animation="180"
              :force-fallback="true"
              :move="handleCenterMove"
              :scroll="true"
              :scroll-sensitivity="160"
              class="drawing-board"
              group="componentsGroup"
              handle=".mover"
              item-key="formItemId"
              tag="el-row"
              @end="onItemEnd"
            >
              <template #item="{ element, index }">
                <form-item-layout
                  :active-id="activeData?.vModel"
                  :current-item="element"
                  :index="index"
                  @active-item="(item, parentItem) => activeFormItem(item, index, parentItem)"
                  @change="updateProjectItemInfo"
                  @change-label="changeLabel"
                  @copy-item="copyDrawingItem"
                  @delete-item="deleteDrawingItem"
                  @add-bank="handleAddToQuestionBank"
                />
              </template>
            </draggable>
          </el-form>
        </div>
      </el-scrollbar>
    </div>
    <right-panel
      :active-data="activeData"
      :fields="drawingList"
      :form-conf="formConf"
      :show-field="!!drawingList.length"
      @add-fields="handleAddFields"
      @data-change="handleActiveDataChange"
    />
    <add-to-question-bank ref="addToQuestionBankRef" />
    <form-bot />
  </div>
</template>
<script lang="ts" name="FormEditor" setup>
import { computed, nextTick, onBeforeMount, onDeactivated, onMounted, onUnmounted, ref, watch } from "vue";
import draggable from "vuedraggable";
import { useRoute } from "vue-router";
import { useThrottleFn, useWindowSize } from "@vueuse/core";
import { cloneDeep, debounce } from "lodash-es";
import FormItemLayout from "./FormItemLayout.vue";
import RightPanel from "./right/RightPanel.vue";
import FormTinymce from "../tinymce/index.vue";
import FormSvgIcon from "../SvgIcon/index.vue";
import { useFormInfo } from "@/stores/formInfo";
import { formDesign } from "./hooks/useFormDesign";
import { useExamForm } from "./hooks/useExamForm";
import mittBus from "@/utils/mitt";
import { useComponents } from "./hooks/useComponents";
import { setThemeVars } from "@/views/formgen/utils/theme";
import { loadAsyncComponent } from "@/utils/asyncComponent";
import AddToQuestionBank from "./fun/AddToQuestionBank.vue";
import AsyncLoading from "@/components/TLoading/asyncLoading.vue";
import FastToolbar from "./fun/FastToolbar.vue";
import { operationHistory } from "./hooks/useOperationHistory";
import TablerCategory2 from "~icons/tabler/category-2";
import TablerBook2 from "~icons/tabler/book-2";
import TablerNotes from "~icons/tabler/notes";
import { useItemTinymceHook } from "@/views/formgen/components/FormDesign/FormItem/hooks/useItemTinymceHook";
import { useFormOption } from "@/views/formgen/components/FormDesign/FormItem/hooks/useFormOption";

const FormQuestion = loadAsyncComponent(() => import("./fun/FormQuestion.vue"));
const FormOutline = loadAsyncComponent(() => import("./fun/FormOutline.vue"));
const FormBot = loadAsyncComponent(() => import("../../../ai/form/FormBot.vue"));

const { setIsSaving } = useFormInfo();

const { height } = useWindowSize();
const wdHeight = ref(height);

const {
  drawingList,
  activeData,
  activeIndex,
  formConf,
  formKey,
  loadData,
  syncAllItem,
  cloneComponent,
  activeFormItem,
  copyDrawingItem,
  updateProjectItemInfo,
  saveProjectItemInfo,
  queryProjectItems,
  isDefaultApi,
  checkFormPublishStatus,
  deleteDrawingItem,
  syncAllItemSorts,
  refreshAllItemSorts,
  activeSubformItem
} = formDesign;

const { execute } = operationHistory;

const centerScrollbarRef = ref<any>(null);
const centerRowsRef = ref<HTMLDivElement>();

const { getAllComponents, getComponentsObj, getFormConfig } = useComponents();

const leftComponents = computed(() => {
  return getAllComponents(formType.value);
});

const formType = computed(() => {
  return formConf.value?.type;
});

const examFormHook = useExamForm();

const totalScore = computed(() => {
  return examFormHook.getTotalScore(drawingList.value);
});

const route = useRoute();

const handleSaveProjectInfo = debounce(() => {
  formDesign.saveProjectInfo();
}, 200);

const addToQuestionBankRef = ref<InstanceType<typeof AddToQuestionBank> | null>(null);

const handleAddToQuestionBank = (item: any) => {
  addToQuestionBankRef.value?.showDialog(item);
};

const props = defineProps({
  /**
   * 是否编辑表单信息
   */
  editFormInfo: {
    type: Boolean,
    default: true
  },
  // 是否是默认表单编辑器 默认状态下走表单的接口 否则将不走任何接口
  isDefault: {
    type: Boolean,
    default: true
  }
});

const loading = ref(true);

onBeforeMount(() => {
  drawingList.value = [];
});

const leftTabActive = ref("components");

onMounted(async () => {
  setThemeVars(null);
  isDefaultApi.value = props.isDefault;
  if (props.isDefault) {
    formKey.value = route.query.key as string;
    formConf.value = cloneDeep(getFormConfig((route.query.type as any) || 1));
    formConf.value!.formKey = formKey.value;
    await loadData();
  }
  loading.value = false;
});

onUnmounted(() => {
  if (props.isDefault) {
    refreshAllItemSorts();
  }
});

onDeactivated(() => {
  if (props.isDefault) {
    refreshAllItemSorts();
  }
  activeData.value = null;
  activeIndex.value = -1;
});

mittBus.on("refreshFormList", () => {
  queryProjectItems();
});

const handleActiveDataChange = async (val: any) => {
  // 特殊处理自增表单 使修改的数据为自增表单组件本身
  let newVal = cloneDeep(val);
  if (val.isChild && activeSubformItem.value) {
    activeSubformItem.value.childList.forEach((item: any, index: number) => {
      if (item.vModel === val.vModel) {
        activeSubformItem.value!.childList[index] = cloneDeep(newVal);
        return;
      }
    });
    newVal = cloneDeep(activeSubformItem.value);
  }
  console.log(newVal);
  updateProjectItemInfo(newVal);
};

const changeLabel = (currentItem: any, value: any) => {
  console.log("----", currentItem, value);
};

const handleMove = () => {
  console.log(formConf.value?.status);
  if (formConf.value?.status == 2) {
    checkFormPublishStatus();
    return false;
  }
  return true;
};

const handleCloneComponent = (obj: any) => {
  execute(drawingList.value);
  return cloneComponent(obj);
};

const onEnd = (obj: any) => {
  if (obj.from !== obj.to) {
    activeIndex.value = obj.newIndex;
    activeData.value = drawingList.value[obj.newIndex];
    // 拖拽到自增表单不单独保存
    if (obj.to.className.indexOf("list-main") > -1) {
      return;
    }
    saveProjectItemInfo(activeData.value).then(() => {
      onItemEnd(obj, true);
    });
  }
};
const handleCenterMove = (obj: any) => {
  execute(drawingList.value);
  // 不允许拖动到子表单区域
  if (obj.to.className === "list-main") {
    return false;
  }
};

const onItemEnd = (obj: any, createNew = false) => {
  setIsSaving(true);
  // createNew 避免新的组件拉到第一个不排序
  if (obj.oldIndex === obj.newIndex && !createNew) {
    setIsSaving(false);
    return;
  }
  syncAllItemSorts();
};

const addComponent = (item: any) => {
  checkFormPublishStatus().then((result: boolean) => {
    if (result) {
      const clone = cloneComponent(item);
      execute(drawingList.value);
      saveProjectItemInfo(clone).then(() => {
        drawingList.value.push(clone);
        activeFormItem(clone, drawingList.value.length - 1);
        scrollToBottom();
      });
    }
  });
};

const scrollToBottom = () => {
  nextTick(() => {
    centerScrollbarRef.value.setScrollTop(centerRowsRef.value!.clientHeight);
  });
};

const designFormRef = ref<any>(null);

const handleFormScrollToField = (prop: string) => {
  designFormRef.value.scrollToField(prop);
};

const handleContentScroll = useThrottleFn(() => {
  window.tinymce.activeEditor.getElement()?.blur();
}, 1000);

/**
 * 新增字段 ocr组件使用
 * @param val
 */
const handleAddFields = (val: any) => {
  let fieldMapping: any = {};
  Object.keys(val).forEach(key => {
    let field = val[key] as any;
    let compo = cloneDeep(getComponentsObj()[field.type]);
    compo.config.label = field.label;
    const clone = cloneComponent(compo);
    drawingList.value.push(clone);
    fieldMapping[key] = clone.config.formId;
  });
  activeData.value!.fieldMapping = fieldMapping;
  console.log(fieldMapping);
  handleActiveDataChange(activeData.value);
  syncAllItem();
};

// 选项富文本处理
const { changeOptionLabel } = useFormOption();
const { initTinymce } = useItemTinymceHook(changeOptionLabel);

watch(
  () => activeData.value?.vModel,
  val => {
    if (val && activeData.value?.config?.options && activeData.value?.config?.optionsType == 0) {
      console.log("init tinymce  ." + activeData.value?.vModel);
      nextTick(() => {
        initTinymce(val || "", (editors: any) => {
          // 某些情况下初始化失败 在尝试一次
          if (!editors || !editors?.length) {
            setTimeout(() => {
              initTinymce(val || "", () => {});
            }, 1000);
          }
        });
      });
    }
  }
);
</script>

<style lang="scss">
@import "../../assets/styles/home.scss";
@import "../../assets/styles/right.scss";
</style>
